#pragma once

#include "Binding/BoundExpression.hpp"
#include "Binding/BoundStatement.hpp"

class BoundTreeRewriter
{
public:
    virtual SharedBoundStatement RewriteStatement(SharedBoundStatement node);

protected:
    virtual SharedBoundStatement RewriteBlockStatement(SharedBoundStatement node);
    virtual SharedBoundStatement RewriteVariableDeclaration(SharedBoundStatement node);
    virtual SharedBoundStatement RewriteIfStatement(SharedBoundStatement node);
    virtual SharedBoundStatement RewriteWhileStatement(SharedBoundStatement node);
    virtual SharedBoundStatement RewriteForStatement(SharedBoundStatement node);
    virtual SharedBoundStatement RewriteExpressionStatement(SharedBoundStatement node);
    virtual SharedBoundStatement RewriteLabelStatement(SharedBoundStatement node);
    virtual SharedBoundStatement RewriteGotoStatement(SharedBoundStatement node);
    virtual SharedBoundStatement RewriteConditionalGotoStatement(SharedBoundStatement node);

    virtual SharedBoundExpression RewriteExpression(SharedBoundExpression node);

    virtual SharedBoundExpression RewriteErrorExpression(SharedBoundExpression node);
    virtual SharedBoundExpression RewriteLiteralExpression(SharedBoundExpression node);
    virtual SharedBoundExpression RewriteVariableExpression(SharedBoundExpression node);
    virtual SharedBoundExpression RewriteAssignmentExpression(SharedBoundExpression node);
    virtual SharedBoundExpression RewriteUnaryExpression(SharedBoundExpression node);
    virtual SharedBoundExpression RewriteBinaryExpression(SharedBoundExpression node);

};